/**
 * Universidad del Valle de Guatemala
 * CC2003 - Algoritmos y Estructuras de Datos
 * HOJA DE TRABAJO #2
 * Oscar Antonio González Natareno 10277
 */


/**
 * CLASE: DriverStack
 * DESCRIPCIÓN: Driver del Stack, en el cual, se ingresan expresiones en "Postfix" para ser evaluadas.
 */

/* SE IMPORTAN LAS CLASES A UTILIZARSE EN EL PROGRAMA */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class DriverStack<E> extends Stack<E> {                              // IMPLEMENTACIÓN DEL STACK GENÉRICO
    
    /* DEFINICIÓN DEL MÉTODO MAIN */
    public static void main(String[] args) throws IOException {
        
        /* DEFINICIÓN DE VARIABLES */
        int i = 0;
        String answer;
        char caracter;
        int oper1, oper2;
        int resultado = 0;
        System.out.println("|---------------------|");
        System.out.println("| CALCULADORA NUMEROS |");
        System.out.println("|---------------------|");
        System.out.println("\n");
        
        String expresion = ingresarExpresion();                             // INGRESO DE LA EXPRESIÓN "POSTFIX" POR PARTE DEL USUARIO
        Stack<String> pila = new Stack<String>();                           // CREACIÓN DE LA PILA DEL TIPO STRING (GENÉRICOS)
                   
        do {
            caracter = expresion.charAt(i);                                 // SE OBTIENE LOS CARACTERES DE LA EXPRESIÓN INGRESADA POR EL USUARIO
            switch (caracter){                                              // SWITCH
                /* NÚMEROS INGRESADOS EN LA EXPRESIÓN */
                case '0':                                                               
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '1':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '2':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '3':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '4':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '5':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '6':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '7':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '8':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                case '9':
                    pila.push(Character.toString(caracter));                // SE INGRESA EL NÚMERO EN LA PILA      
                    break;
                /* OPERACIONES INGRESADAS EN LA EXPRESIÓN */ 
                case '+':
                    if (pila.size() < 2) {
                        System.out.println("INGRESO NO VALIDO");  
                        System.exit(0);   
                    }
                    oper1 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL PRIMER OPERANDO
                    oper2 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL SEGUNDO OPERANDO
                    resultado = oper1 + oper2;                              // OPERATORIA
                    answer = String.valueOf(resultado);                     // SE OBTIENE EL RESULTADO DE LA OPERATORIA
                    pila.push(answer);                                      // SE ALMACENA EL RESULTADO EN LA PILA
                    break;
                case '-':
                    if (pila.size() < 2) {
                        System.out.println("INGRESO NO VALIDO");  
                        System.exit(0);   
                    }
                    oper1 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL PRIMER OPERANDO
                    oper2 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL SEGUNDO OPERANDO
                    resultado = oper1 - oper2;                              // OPERATORIA
                    answer = String.valueOf(resultado);                     // SE OBTIENE EL RESULTADO DE LA OPERATORIA
                    pila.push(answer);                                      // SE ALMACENA EL RESULTADO EN LA PILA
                    break;
                case '*':
                    if (pila.size() < 2) {
                        System.out.println("INGRESO NO VALIDO");  
                        System.exit(0);   
                    }
                    oper1 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL PRIMER OPERANDO
                    oper2 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL SEGUNDO OPERANDO          
                    resultado = oper1 * oper2;                              // OPERATORIA     
                    answer = String.valueOf(resultado);                     // SE OBTIENE EL RESULTADO DE LA OPERATORIA
                    pila.push(answer);                                      // SE ALMACENA EL RESULTADO EN LA PILA     
                    break;
                case '/':
                    if (pila.size() < 2) {
                        System.out.println("INGRESO NO VALIDO");  
                        System.exit(0);   
                    }
                    oper1 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL PRIMER OPERANDO
                    oper2 = Integer.parseInt(pila.pop());                   // SE OBTIENE EL SEGUNDO OPERANDO
                    resultado = oper1 / oper2;                              // OPERATORIA     
                    answer = String.valueOf(resultado);                     // SE OBTIENE EL RESULTADO DE LA OPERATORIA            
                    pila.push(answer);                                      // SE ALMACENA EL RESULTADO EN LA PILA               
                    break;
               /* FINALIZACIÓN DE LA EXPRESIÓN INGRESADA */         
               case '=':
                    System.out.print("\n");
                    System.out.print("* EL RESULTADO ES: ");
                    System.out.println(pila.pop());                         // SE IMPRIME EL RESULTADO DE LA EXPRESIÓN POSTFIX EVALUADA
                    break;
                case ' ':
                    break;                                                  // SE IGNORAN LOS ESPACIOS
                /* INGRESO NO VÁLIDO */    
                default:
                    System.out.println("INGRESO NO VALIDO");                
                    System.exit(0);                                         // FINALIZA LA EJECUCIÓN DEL PROGRAMA SI SE INGRESA UN CARACTER NO VÁLIDO EN LA EXPRESIÓN     
                    break;                 
            }
            i++;    
        } while (i < expresion.length());                                   // SE REPITE HASTA QUE NO FINALICE LA EXPRESIÓN INGRESADA
    }
    
    /* MÉTODO INGRESARLINEA */
    /**
     * Permite el ingreso de la expresión "Postfix" por parte del usuario
     * Expresión "Postfix" ingresada por el usuario.
     * IOException 
     */
        public static String ingresarExpresion() throws IOException {
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));                                                // CREACIÓN DEL BUFFER PARA EL INGRESO DE LA EXPRESIÓN POSTFIX
        System.out.print("* Ingrese la expresión POSTFIX a evaluar (PARA FINALIZAR LA EXPRESIÓN, INGRESE EL SÍMBOLO '='):  ");     // PETICIÓN DE INGRESO AL USUARIO       
        String ingreso = input.readLine();                                  // SE OBTIENE EL INGRESO POR PARTE DEL USUARIO                   
        return ingreso;                                                     // SE DEVUELVE LA EXPRESIÓN INGRESADA
    }
    
} // FIN DEL DRIVER 


